#include <Windows.h>
#include "Exceptions/Exception.h"
#include "Logger\Logger.h"
#include "Base.h"
#include "Engine.h"
#include "GameProcess.h"

#if defined (_DEBUG)
#include "Memory\MemLeaks.h"
#endif

#if defined (_DEBUG)
#define APPLICATION_NAME	"VIDEOGAME DEBUG"
#else
#define APPLICATION_NAME	"VIDEOGAME RELEASE"
#endif

CEngine *g_pEngine = NULL;
CGameProcess* g_pGameProcess = NULL;

void ShowErrorMessage (const std::string& message);

/************************************************************************/
/* The window's message handler                                         */
/************************************************************************/
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	switch( msg )
	{
	case WM_DESTROY:
		{
			PostQuitMessage( 0 );
			return 0;
			break;
		}		
	case WM_KEYDOWN:
		{
			switch( wParam )
			{
			case VK_ESCAPE:
				PostQuitMessage( 0 );

				return 0;
				break;
			}
			break;
		}
	}//end switch( msg )

	return DefWindowProc( hWnd, msg, wParam, lParam );
}


/************************************************************************/
/* WinMain																*/
/************************************************************************/
int APIENTRY WinMain(HINSTANCE _hInstance, HINSTANCE _hPrevInstance, LPSTR _lpCmdLine, int _nCmdShow)
{
	// Register the window class
	WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, APPLICATION_NAME, NULL };
	
	RegisterClassEx( &wc );
	
	try
	{
		// Create the application's window
		HWND hWnd = CreateWindow( APPLICATION_NAME, APPLICATION_NAME, WS_OVERLAPPEDWINDOW, 
			100, 100, 800, 600, NULL, NULL, wc.hInstance, NULL );

		ShowWindow( hWnd, SW_SHOWDEFAULT );
		UpdateWindow( hWnd );
		MSG msg;
		ZeroMemory( &msg, sizeof(msg) );

		g_pGameProcess = new CGameProcess();

		g_pEngine = new CEngine();
		g_pEngine->SetProcess(g_pGameProcess);

		g_pEngine->Initialize(hWnd);

		//Bucle principal
		while( msg.message != WM_QUIT )
		{
			if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
			{
				TranslateMessage( &msg );
				DispatchMessage( &msg );
			}
			else
			{
				g_pEngine->Update();
				g_pEngine->Render();
			}
		}
	}
	catch (CException& e)
	{
		ShowErrorMessage(e.GetDescription());
	}

	UnregisterClass( APPLICATION_NAME, wc.hInstance );

	CHECKED_DELETE(g_pEngine);

	return 0;
}

/************************************************************************/
/* Shows an error message if an exceptions is thrown                    */
/************************************************************************/
void ShowErrorMessage (const std::string& message)
{
	bool logSaved = false;

	logSaved = LOGGER->SaveLogsInFile();

	std::string end_message = "";
	if (logSaved)   
	{
		end_message += "Sorry, Application failed. Logs saved\n";
	}
	else
	{ 
		end_message += "Sorry, Application failed. Logs could not be saved\n";
	}
	end_message += message;
	MessageBox(0, end_message.c_str(), "FlostiProject Report", MB_OK | MB_ICONERROR);
}